home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Development & Debugging Tools / RenameGXHeaders tool / RenameGXHeaders.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-07  |  12.2 KB  |  436 lines  |  [TEXT/MPS ]

  1.  
  2.  
  3. /*
  4.     File:        RenameGXHeaders.c
  5.  
  6.     Contains:    MPW tool to replace old header names with new header names.
  7.                 Omits multiple inclusions of the same new header.
  8.                 
  9.                 Version 1.0
  10.  
  11.     Written by:    John Daggett, with parts taken from the Skia preprocess tool
  12.     
  13.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  14.  
  15.     Change History (most recent first):
  16.  
  17.          <3>      7/7/95    jtd        revving for changes in GX printing headers
  18.          <2>      4/5/95    jtd        fixed comments a bit
  19.          <1>      4/5/95    jtd        First checked in.
  20. */
  21.  
  22. #include <ctype.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <CursorCtl.h>
  27.  
  28. typedef enum { false, true } boolean;
  29.  
  30. void fprintTrueFalse (FILE *fp, boolean trueOrFalse) {
  31.     if ( trueOrFalse ) 
  32.         fprintf (fp, "True");
  33.     else
  34.         fprintf (fp, "False");
  35. }
  36.  
  37. typedef struct {
  38.     boolean    alreadyReplaced;    /* to avoid multiple inclusions of the same file */
  39.     boolean system;                /* need to transform "" to <> for system headers */
  40.     char    newName[32];        /* name with no spaces */
  41. } NewHeader;
  42.  
  43. typedef struct {
  44.     char    oldName[32];        /* name with spaces */
  45.     int        newIndex;            /* index into table of new names */
  46. } OldHeader;
  47.  
  48. /* new GX header names - no spaces and prefixed with GX   */
  49. /* Warning: oldxxxx[] must be kept in sync with new[]!!!! */
  50. NewHeader new[] = {
  51.     { false, true, "GXEnvironment.h" },                /* 0 */
  52.     { false, true, "GXErrors.h" },                    /* 1 */
  53.     { false, true, "GXFonts.h" },                    /* 2 */
  54.     { false, true, "GXGraphics.h" },                /* 3 */
  55.     { false, true, "GXLayout.h" },                    /* 4 */
  56.     { true,  true, "GXLinkage.h" },                    /* 5 */        /* no longer needed! */
  57.     { false, true, "GXMath.h" },                    /* 6 */
  58.     { false, true, "GXTypes.h" },                    /* 7 */
  59.     { false, true, "GXGraphicsPriv.h" },            /* 8 */
  60.     { false, true, "ScalerPriv.h" },                /* 9 */
  61.     { false, true, "ScalerTypes.h" },                /* 10 */
  62.     { false, true, "SFNTTypes.h" },                    /* 11 */
  63.     { false, false, "CameraLibrary.h" },            /* 12 */
  64.     { false, false, "ColorLayoutLibrary.h" },        /* 13 */
  65.     { false, false, "FontLibrary.h" },                /* 14 */
  66.     { false, false, "FontMenuLibrary.h" },            /* 15 */
  67.     { false, false, "GraphicsLibraries.h" },        /* 16 */
  68.     { false, false, "GraphicsStateLibrary.h" },        /* 17 */
  69.     { false, false, "GraphicsToolboxLibrary.h" },    /* 18 */
  70.     { false, false, "GraphicsBugLibrary.h" },        /* 19 */
  71.     { false, false, "LayoutEditLibrary.h" },        /* 20 */
  72.     { false, false, "LayoutLibrary.h" },            /* 21 */
  73.     { false, false, "OffscreenLibrary.h" },            /* 22 */
  74.     { false, false, "QDLibrary.h" },                /* 23 */
  75.     { false, false, "ScalerLibrary.h" },            /* 24 */
  76.     { false, false, "SelectionLibrary.h" },            /* 25 */
  77.     { false, false, "ShapeControlsLibrary.h" },        /* 26 */
  78.     { false, false, "StorageLibrary.h" },            /* 27 */
  79.     { false, false, "TrueTypeLibrary.h" },            /* 28 */
  80.     { false, false, "LayoutFeatureConstants.h" },    /* 29 */
  81.     { false, true, "GXPrinterDrivers.h" },            /* 30 */
  82.     { false, true, "GXPrinting.h" },                /* 31 */
  83.     { false, true, "GXMessages.h" }                    /* 32 */
  84. };
  85.  
  86. /* original GX header names with spaces */
  87. /* last entry is empty as a flag to stop searching */
  88. OldHeader oldWithSpaces[] = {
  89.     { "graphics errors.h", 1 },
  90.     { "graphics debugging.h", 1 },
  91.     { "graphics toolbox.h", 0 },
  92.     { "graphics macintosh.h", 0 },
  93.     { "math types.h", 6 },
  94.     { "math routines.h", 6 },
  95.     { "font routines.h", 2 },
  96.     { "graphics routines.h", 3 },
  97.     { "layout routines.h", 4 },
  98.     { "font types.h", 7 },
  99.     { "layout types.h", 7 },
  100.     { "graphics types.h", 7 },
  101.     { "graphics stream types.h", 7 },
  102.     { "synonym tags.h", 7 },
  103.     { "graphics linkage.h", 5 },
  104.     { "private graphics routines.h", 8 },
  105.     { "scaler components.h", 9 },
  106.     { "scaler routines.h", 9 },
  107.     { "scaler types.h", 10 },
  108.     { "sfnt types.h", 11 },
  109.     { "camera library.h", 12 },
  110.     { "color layout library.h", 13 },
  111.     { "font library.h", 14 },
  112.     { "font menu library.h", 15 },
  113.     { "graphics libraries.h", 16 },
  114.     { "graphics state library.h", 17 },
  115.     { "graphics toolbox library.h", 18 },
  116.     { "graphicsBug library.h", 19 },
  117.     { "layout edit library.h", 20 },
  118.     { "layout library.h", 21 },
  119.     { "offscreen library.h", 22 },
  120.     { "qd library.h", 23 },
  121.     { "scaler library.h", 24 },
  122.     { "selection library.h", 25 },
  123.     { "shape controls library.h", 26 },
  124.     { "storage library.h", 27 },
  125.     { "truetype library.h", 28 },
  126.     { "PrintingDrivers.h", 30 },
  127.     { "PrintingExtensions.h", 30 },
  128.     { "PrintingManager.h", 31 },
  129.     { "PrintingMessages.h", 31 },
  130.     { "PrintingErrors.h", 31 },
  131.     { "PrintingResTypes.h", 31 },
  132.     { "Messages.h", 32 },
  133.     { "", -1 }
  134. };
  135.  
  136. /* original GX headers without spaces in the name */
  137. /* only needed for Apple internal use             */
  138. OldHeader oldNoSpaces[] = {
  139.     { "GraphicsErrors.h", 1 },
  140.     { "GraphicsDebugging.h", 1 },
  141.     { "GraphicsToolbox.h", 0 },
  142.     { "GraphicsMacintosh.h", 0 },
  143.     { "MathTypes.h", 6 },
  144.     { "MathRoutines.h", 6 },
  145.     { "FontRoutines.h", 2 },
  146.     { "GraphicsRoutines.h", 3 },
  147.     { "LayoutRoutines.h", 4 },
  148.     { "FontTypes.h", 7 },
  149.     { "LayoutTypes.h", 7 },
  150.     { "GraphicsTypes.h", 7 },
  151.     { "GraphicsStreamTypes.h", 7 },
  152.     { "SynonymTags.h", 7 },
  153.     { "GraphicsLinkage.h", 5 },
  154.     { "PrivateGraphicsRoutines.h", 8 },
  155.     { "TranslatorRoutines.h", 8 },
  156.     { "ScalerComponents.h", 9 },
  157.     { "ScalerRoutines.h", 9 },
  158.     { "", -1 }
  159. };
  160.  
  161. /* by default, convert names with spaces (use -i option to change) */
  162. OldHeader *old = oldWithSpaces;
  163.  
  164. #define kMaxLineLength    1024
  165. #define    kSpinTime         7
  166. #define kIncludeString    "#include"
  167. #define kIncludeLength    8
  168. #define kIfString        "#if"
  169. #define kEndifString    "#endif"
  170.  
  171. #define equalstring(a, b)    ( strncmp((a), (b), strlen(b)) == 0 )
  172.  
  173. /* default options */
  174. boolean        gQuiet = false,        /* output replacements and omissions */
  175.             gOverwrite = false;    /* write over input file */
  176.             gSystem = true,     /* change "" includes to <> includes for certain headers */
  177.             gInternal = false;    /* converting from names without spaces */
  178.  
  179. /* globals */
  180. boolean        gSkipping = false, gNesting = false;
  181.  
  182. /* match - skip over whitespace before trying to match a string */
  183. boolean match (char *s, char *match) {
  184.     while (isspace(*s)) s++;
  185.     if ( (equalstring(s, match)) ) return true;
  186.     return false;
  187. }
  188.  
  189. /* replace an old GX header name with a new one */
  190. /* <whitespace>* #include <whitespace>* ['"' | '<'] <header name> ['"' | '>'] <any char>* */
  191. boolean replaceInclude (char *s, FILE *out) {
  192.     char *start = s, *begin, *end, left, right;
  193.     OldHeader *h = old;
  194.     
  195.     /* white space before #include */
  196.     while (isspace(*s)) s++;
  197.  
  198.     if ( !(equalstring(s, kIncludeString)) ) {
  199.         fputs (start, out);
  200.         return false;
  201.     }
  202.  
  203.     s += kIncludeLength;
  204.     while (isspace(*s)) s++;
  205.     
  206.     /* read until the " or < */
  207.     if ( *s != '\"' && *s != '<' ) {
  208.         fputs (start, out);
  209.         return false;
  210.     }
  211.     left = *s;
  212.     begin = ++s;
  213.  
  214.     while ( *s != '\"' && *s != 0 && *s != '>' ) s++;
  215.     if ( *s == 0 ) {
  216.         fputs (start, out);
  217.         return false;
  218.     }
  219.     right = *s;
  220.     end = ++s;
  221.     
  222.     /* linear search for the old name */
  223.     while ( *h->oldName != 0 ) {
  224.         if ( equalstring(begin, h->oldName) ) {
  225.  
  226.             /* found the name, now replace it with the new name */
  227.             *(begin - 1) = *(end - 1) = 0;
  228.             if ( new[h->newIndex].system ) {
  229.                 left = '<';
  230.                 right = '>';
  231.             }
  232.             if ( new[h->newIndex].alreadyReplaced ) {
  233.                 if ( !gQuiet ) fprintf (stderr, "\tskipped replacing '%s' with %s\n", begin, new[h->newIndex].newName);
  234.                 gSkipping = true;
  235.             } else {
  236.                 if ( !gQuiet ) fprintf (stderr, "\treplaced '%s' with %s\n", begin, new[h->newIndex].newName);
  237.                 new[h->newIndex].alreadyReplaced = true;
  238.                 fputs (start, out);
  239.                 fputc (left, out);
  240.                 fputs (new[h->newIndex].newName, out);
  241.                 fputc (right, out);
  242.                 fputs (end, out);
  243.             }
  244.             return true;
  245.         }
  246.         h++;
  247.     }
  248.     
  249.     fputs (start, out);
  250.     return false;
  251. }
  252.  
  253.  
  254. /* Note:    nested if's present a problem, for when the inclusion of a header
  255.             file is within an if, it may be appropriate to leave multiple
  256.             #include's of the same file.
  257.             
  258.             Example:
  259.                 
  260.                 #if blah
  261.                     #include "graphics types.h"
  262.                 #else
  263.                     #include "layout types.h"
  264.                 #endif
  265.             
  266.             Since both will map to GXTypes.h, omitting the second #include will result
  267.             in incorrect code.  Rather than try and create a much fancier tool, the user
  268.             of this tool should always verify the output of this tool when #include's 
  269.             are surrounded by #ifdef's and skipping occurs.
  270.             
  271.             This tool can warn the user when #if statements are present but this
  272.             is a hack and not a real solution to the problem.
  273. */
  274.             
  275. /* processData - read in lines from a file, keeping track of nested if's */
  276. void processData (FILE *in, FILE *out) {
  277.     int    line = 0;
  278.     char buffer[kMaxLineLength];
  279.     static int nestingLevel = 0, replacedNesting = -1;
  280.     
  281.     while( fgets(buffer,sizeof(buffer),in) ) {
  282.         if ( replaceInclude (buffer, out) ) {
  283.             if ( replacedNesting == -1 ) {
  284.                 replacedNesting = nestingLevel;
  285.             } else if ( replacedNesting != nestingLevel ) {
  286.                 gNesting = true;
  287.             }
  288.         } else if ( match(buffer, kIfString) ) {
  289.             nestingLevel++;
  290.         } else if ( match(buffer, kEndifString) ) {
  291.             nestingLevel--;
  292.         }            
  293.     }
  294. }
  295.  
  296. void printUsageAndExit (char *progname) {
  297. #ifdef NOSPACESOPTION
  298.     fprintf(stderr, "usage:  %s  [-iqsw] [input] [-o output]\n", progname);
  299. #else
  300.     fprintf(stderr, "usage:  %s  [-qsw] [input] [-o output]\n", progname);
  301. #endif
  302.     fprintf(stderr, "where\n");
  303. #ifdef NOSPACESOPTION
  304.     fprintf(stderr, "\t\t\t-i\tconvert from names with no spaces (Default: ");
  305.     fprintTrueFalse(stderr, gInternal);
  306.     fprintf(stderr, ")\n");
  307. #endif
  308.     fprintf(stderr, "\t\t\t-q\tquiet mode (Default: ");
  309.     fprintTrueFalse(stderr, gQuiet);
  310.     fprintf(stderr, ")\n");
  311.  
  312.     fprintf(stderr, "\t\t\t-s\tinsert <> around system headers (Default: ");
  313.     fprintTrueFalse(stderr, gSystem);
  314.     fprintf(stderr, ")\n");
  315.  
  316.     fprintf(stderr, "\t\t\t-w\twrite over input file (Default: ");
  317.     fprintTrueFalse(stderr, gOverwrite);
  318.     fprintf(stderr, ")\n");
  319.  
  320.     fprintf(stderr, "\n");
  321.     exit(1);
  322. }
  323.  
  324. main(int argc, char *argv[])
  325. {
  326.     FILE *in = stdin, *out = stdout;
  327.     char *progname = argv[0], *p, *infile, buffer[kMaxLineLength];
  328.     
  329.     argv++;
  330.     while (--argc > 0) {
  331.         p = *argv++;
  332.  
  333.         if (*p == '-') {
  334.             switch (p[1]) {
  335.  
  336.             /* output filename */
  337.             case 'o':
  338.                 if (--argc < 0) printUsageAndExit(progname);
  339.                 p = *argv++;
  340.                 out = fopen(p, "w");
  341.                 if (!out) {
  342.                     fprintf(stderr, "%s:  couldn't open %s\n", progname, p);
  343.                     return 1;
  344.                 }
  345.                 break;
  346.  
  347.             /* run in quiet mode */
  348.             case 'q':
  349.                 gQuiet = true;
  350.                 break;
  351.  
  352.             /* undocumented option - converts headers with no spaces in the name */
  353.             case 'i':
  354.                 gInternal = true;
  355.                 old = oldNoSpaces;
  356.                 break;
  357.             
  358.             /* convert "" includes to <> includes where appropriate */    
  359.             case 's':
  360.                 gSystem = true;
  361.                 break;
  362.                 
  363.             /* overwrite the input file */
  364.             case 'w':
  365.                 gOverwrite = true;
  366.                 break;
  367.                 
  368.             /* user needs help */
  369.             case 'h':
  370.             case 'u':
  371.             case '?':
  372.             default:
  373.                 printUsageAndExit(progname);
  374.  
  375.             }
  376.  
  377.         } else if (in == stdin) {
  378.             infile = p;
  379.             in = fopen(infile, "r");
  380.             if (!in) {
  381.                 fprintf(stderr, "%s:  couldn't open %s\n", progname, infile);
  382.                 return 1;
  383.             }
  384.         } else {
  385.             if (out != stdout) printUsageAndExit(progname);
  386.             out = fopen(p, "w");
  387.             if (!out) {
  388.                 fprintf(stderr, "%s:  couldn't open %s\n", progname, p);
  389.                 return 1;
  390.             }
  391.         }
  392.     }
  393.     
  394.     if ( gOverwrite ) {
  395.         if ( out != stdout ) printUsageAndExit(progname);
  396.         out = tmpfile();
  397.         if (!out) {
  398.             fprintf(stderr, "%s:  couldn't create a temporary file\n", progname);
  399.             return 1;
  400.         }
  401.     }
  402.  
  403.     processData (in, out);
  404.     
  405.     if ( gOverwrite ) {
  406.         rewind(out);
  407.         in = freopen (infile, "w", in);
  408.         if ( !in ) {
  409.             fprintf (stderr, "%s:    couldn't open %s for writing\n", progname, infile);
  410.             return 1;
  411.         }
  412.         while( fgets(buffer,sizeof(buffer),out) ) fputs(buffer,in);
  413.     }
  414.     
  415.     /* nested if checking turned off */
  416. #if NOSPACESOPTION    
  417.     if ( gNesting && gSkipping ) fprintf (stderr, "\tWARNING: Skipping in a file with nested if's!\n");
  418. #endif
  419.     if ( gSkipping && !gQuiet ) {
  420.         fprintf (stderr, "Note:\n");
  421.         fprintf (stderr, "    Since the GX headers have been consolidated, several old GX headers often map to one new\n");
  422.         fprintf (stderr, "    GX header.  This tool omits multiple inclusion of the same header file.  This may be \n");
  423.         fprintf (stderr, "    incorrect in some rare cases.  For example,\n");
  424.         fprintf (stderr, "    \n");
  425.         fprintf (stderr, "        #ifdef usingJustFonts\n");
  426.         fprintf (stderr, "            #include \"font types.h\"\n");
  427.         fprintf (stderr, "        #else\n");
  428.         fprintf (stderr, "            #include \"graphics types.h\"\n");
  429.         fprintf (stderr, "        #endif\n");
  430.         fprintf (stderr, "    \n");
  431.         fprintf (stderr, "    Since both of these old headers map to GXTypes.h, the second #include line would be\n");
  432.         fprintf (stderr, "    omitted incorrectly.  Be sure verify that this is not the case.\n");
  433.     }
  434.     return 0;
  435. }
  436.